<?php
/*
 * This file is part of SoftSite.
 *
 * (c) 2012 Steve Tredinnick
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 *
 *
 * @package softsite
 * @author  Steve Tredinnick <steve.tredinnick@gmail.com>
 */

namespace Lib\Forms\Elements;

use Lib\Forms\BaseElement;

if(!defined('IN_APP'))
{
    Die("Direct Access to PHP Scripts is not permitted");
}


class InputElement extends BaseElement
{
    protected $accept;
    protected $alt;
    protected $Attribute;
    protected $autocomplete;
    protected $autofocus;
    protected $checked;
    protected $disabled;
    protected $formaction;
    protected $formenctype;
    protected $formmethod;
    protected $form;
    protected $formnovalidate;
    protected $formtarget;
    protected $height;
    protected $label;
    protected $list;
    protected $maxlength;
    protected $max;
    protected $min;
    protected $multiple;
    protected $name;
    protected $pattern;
    protected $placeholder;
    protected $readonly;
    protected $required;
    protected $size;
    protected $src;
    protected $step;
    protected $text;
    protected $type;
    protected $value;
    protected $width;

    public function __construct()
    {
        parent::__construct();
    }

    public function GenerateHtml()
    {
        $this->formHtml = $this->label;
        $this->formHtml .= "<input";
        $this->formHtml .= $this->type;
        $this->formHtml .= $this->name;
        $this->formHtml .= $this->alt;
        $this->formHtml .= $this->accept;
        $this->formHtml .= $this->autocomplete;
        $this->formHtml .= $this->autofocus;
        $this->formHtml .= $this->checked;
        $this->formHtml .= $this->disabled;
        $this->formHtml .= $this->form;
        $this->formHtml .= $this->formaction;
        $this->formHtml .= $this->formenctype;
        $this->formHtml .= $this->formmethod;
        $this->formHtml .= $this->formnovalidate;
        $this->formHtml .= $this->formtarget;
        $this->formHtml .= $this->height;
        $this->formHtml .= $this->list;
        $this->formHtml .= $this->max;
        $this->formHtml .= $this->maxlength;
        $this->formHtml .= $this->min;
        $this->formHtml .= $this->multiple;
        $this->formHtml .= $this->pattern;
        $this->formHtml .= $this->placeholder;
        $this->formHtml .= $this->readonly;
        $this->formHtml .= $this->required;
        $this->formHtml .= $this->size;
        $this->formHtml .= $this->src;
        $this->formHtml .= $this->step;
        $this->formHtml .= $this->value;
        $this->formHtml .= $this->width;
        $this->formHtml .= "/>";
        $this->formHtml .= $this->text;
    }

    protected function SetAttribute($Attribute)
    {
        $this->Attribute = $Attribute;
    }

    /**
     * The accept attribute specifies the types of files that the server accepts (that can be submitted through a file upload).
     * Note: The accept attribute can only be used with <input type="file">.
     * Tip: Do not use this attribute as a validation tool. File uploads should be validated on the server.
     *
     * @param string $accept  type of file the server accepts
     */
    protected function SetAccept($accept)
    {
        //TODO: SetAccept needs to allow valid MIME types see http://www.iana.org/assignments/media-types/index.html for details
        if($accept == "audio/*" || $accept == "video/*" || $accept == "image/*")
        {
            $this->accept = " accept='".$accept."' ";
        }
        else
        {
            $this->error->ThrowError(WARNING, "SetAccept method has invalid value, valid values are audio/* , video/* , image/* .", $_SERVER['PHP_SELF'], __LINE__);
        }
    }


    /**
     * The alt attribute provides an alternate text for the user, if he/she for some reason cannot view the image (because of slow connection,
     * an error in the src attribute, or if the user uses a screen reader).
     * Note: The alt attribute can only be used with <input type="image">.
     *
     * @param string $alt alternate text for an image
     */
    protected function SetAlt($alt)
    {
        $this->alt = "alt='".$alt."' ";
    }

    /**
     * The autocomplete attribute specifies whether or not an input field should have autocomplete enabled.
     * Autocomplete allows the browser to predict the value.
     * When a user starts to type in a field, the browser should display options to fill in the field, based on earlier typed values.
     *
     * Note: The autocomplete attribute works with the following <input> types: text, search, url, tel, email, password, datepickers, range, and color.
     * @param bool $autocomplete sets autocomplete on or off.
     */
    protected function SetAutocomplete($autocomplete = true)
    {
        if($autocomplete)
        {
            $this->autocomplete = " autocomplete='on' ";
        }
        else
        {
            $this->autocomplete = " autocomplete='off' ";
        }
    }


    /**
     * When present, it specifies that an <input> element should automatically get focus when the page loads.
     */
    public function SetAutofocus()
    {
        $this->autofocus = " autofocus ";
    }

    /*
    * The checked attribute is a boolean attribute.
     * When present, it specifies that an <input> element should be pre-selected (checked) when the page loads.
     * The checked attribute can be used with <input type="checkbox"> and <input type="radio">.
     * The checked attribute can also be set after the page load, with a JavaScript.
     *
     * @param bool $checked checked state.
    */
    protected function SetChecked($checked = false)
    {

        if(!is_bool($checked))
        {
            $this->error->ThrowError(WARNING, "SetChecked method of a checkbox can only accept a boolean value.", $_SERVER['PHP_SELF'], __LINE__);
        }

        if ($checked)
        {
            $this->checked = " checked ";
        }
        else
        {
            $this->checked = "";
        }
    }


    /**
     * The disabled attribute is a boolean attribute.
     * When present, it specifies that the <input> element should be disabled.
     * A disabled input element is unusable and un-clickable.
     * The disabled attribute can be set to keep a user from using the <input> element until some other condition has been met (like selecting a checkbox, etc.). Then, a JavaScript could remove the disabled value, and make the <input> element usable.
     * Tip: Disabled <input> elements in a form will not be submitted.
     *
     * Note: The disabled attribute will not work with <input type="hidden">.
     *
     * @param bool $disabled
     */
    public function SetDisabled($disabled)
    {
        $this->disabled = $disabled;
    }

    protected function SetForm($form)
    {
        //TODO: Set Form for input types
    }

    protected function SetFormaction($formaction)
    {
        //TODO: Set FormAction for input types
    }

    protected function SetFormenctype($formenctype)
    {
        //TODO: Set Form Enc Type for input types
    }

    protected function SetFormmethod($formmethod)
    {
        //TODO: Set Form Method for input types
    }

    protected function SetFormnovalidate($formnovalidate)
    {
        //TODO: Set Form No Validate for input types
    }

    protected function SetFormtarget($formtarget)
    {
        //TODO: Set Form Target for input types
    }

    /**
     * The height attribute specifies the height of the <input> element.
     * Note: The height attribute is used only with <input type="image">.
     * Tip: Always specify both the height and width attributes for images.
     * If height and width are set, the space required for the image is reserved when the page is loaded.
     * However, without these attributes, the browser does not know the size of the image, and cannot reserve the appropriate space to it.
     * The effect will be that the page layout will change during loading (while the images load).
     * @param int $height
     */
    protected function SetHeight($height)
    {
        $this->height = " height='".$height."' ";
    }


    protected function SetList($list)
    {
        //TODO: Implement DATA LISTS... Currently Only supported in Chrome and Opera.
    }

    /**
     * Generates a label the preceeds the control.
     *
     * @param string $label the label to display before the control.
     */
    public function SetLabel($label)
    {
        $this->label = $label;
    }

    /**
     *
     * The max attribute specifies the maximum value for an <input> element.
     * Tip: Use the max attribute together with the min attribute to create a range of legal values.
     * Note: The max and min attributes works with the following input types: number, range, date, datetime, datetime-local, month, time and week.
     *
     * @param string $max number or date representing the max value of the control
     */
    protected function SetMax($max)
    {
        $this->max = " max='".$max."' ";
    }

    /**
     * The maxlength attribute specifies the maximum number of characters allowed in the <input> element.
     *
     * @param $maxlength
     */
    protected function SetMaxLength($maxlength)
    {
        $this->maxlength = " maxlength='".$maxlength."' ";
    }


    /**
     * The min attribute specifies the minimum value for an <input> element.
     * Tip: Use the min attribute together with the max attribute to create a range of legal values.
     * Note: The max and min attributes works with the following input types: number, range, date, datetime, datetime-local, month, time and week.
     *
     * @param $min
     */
    protected function SetMin($min)
    {
        $this->min = " min='".$min."' ";
    }

    /**
     * The multiple attribute is a boolean attribute.
     * When present, it specifies that the user is allowed to enter more than one value in the <input> element.
     * Note: The multiple attribute works with the following input types: email, and file.
     *
     * @param bool $multiple
     */
    protected function SetMultiple($multiple)
    {
        if(!is_bool($multiple))
        {
            $this->error->ThrowError(WARNING, "SetMultiple method  can only accept a boolean value.", $_SERVER['PHP_SELF'], __LINE__);
        }

        if ($multiple)
        {
            $this->multiple = " multiple ";
        }
        else
        {
            $this->multiple = "";
        }
    }

    /**
     * The name attribute specifies the name of an <input> element.
     * The name attribute is used to reference elements in a JavaScript, or to reference form data after a form is submitted.
     * Note: Only form elements with a name attribute will have their values passed when submitting a form.
     *
     * @param string $name
     */
    protected function SetName($name)
    {
        $this->name = " name='".$name."' ";
    }

    /**
     * The pattern attribute specifies a regular expression that the <input> element's value is checked against.
     * Note: The pattern attribute works with the following input types: text, search, url, tel, email, and password.
     *
     * @param string $pattern
     */
    protected function SetPattern($pattern)
    {
        $this->pattern = " pattern='".$pattern."' ";
        //TODO: Implement global TITLE attribute to display to users pattern mismatch examples.
    }


    /**
     * The placeholder attribute specifies a short hint that describes the expected value of an input field (e.g. a sample value or a short description of the expected format).
     * The hint is displayed in the input field when it is empty, and disappears when the field gets focus.
     * Note: The placeholder attribute works with the following input types: text, search, url, tel, email, and password.
     *
     * @param string $placeholder
     */
    protected function SetPlaceholder($placeholder)
    {
        $this->placeholder = " placeholder='".$placeholder."' ";
    }


    /**
     * The readonly attribute is a boolean attribute.
     * When present, it specifies that an input field is read-only.
     * A read-only input field cannot be modified (however, a user can tab to it, highlight it, and copy the text from it).
     * The readonly attribute can be set to keep a user from changing the value until some other conditions have been met (like selecting a checkbox, etc.).
     * Then, a JavaScript can remove the readonly value, and make the input field editable.
     *
     * TODO: Some fields are exempt from readonly needs implementing. hidden, range, color, checkbox, radio, file, or a button type.
     *
     * @param $readonly
     */
    public function SetReadonly($readonly)
    {
        if(!is_bool($readonly))
        {
            $this->error->ThrowError(WARNING, "SetReadonly method  can only accept a boolean value.", $_SERVER['PHP_SELF'], __LINE__);
        }

        if ($readonly)
        {
            $this->readonly = " readonly ";
        }
        else
        {
            $this->readonly = "";
        }
    }


    /**
     * The required attribute is a boolean attribute.
     * When present, it specifies that an input field must be filled out before submitting the form.
     * Note: The required attribute works with the following input types: text, search, url, tel, email, password, date pickers, number, checkbox, radio, and file.
     *
     * @param bool $required
     */
    protected function SetRequired($required)
    {
        if(!is_bool($required))
        {
            $this->error->ThrowError(WARNING, "SetReadonly method  can only accept a boolean value.", $_SERVER['PHP_SELF'], __LINE__);
        }

        if ($required)
        {
            $this->required = " required ";
        }
        else
        {
            $this->required = "";
        }
    }

    /**
     * The size attribute specifies the visible width, in characters, of an <input> element.
     * Note: The size attribute works with the following input types: text, search, tel, url, email, and password.
     * Tip: To specify the maximum number of characters allowed in the <input> element, use the maxlength attribute.
     *
     * @param $size
     */
    protected function SetSize($size)
    {
        $this->type = " size='".$size."' ";
    }

    /**
     * The src attribute specifies the URL of the image to use as a submit button.
     * Note: The src attribute is required for <input type="image">, and can only be used with <input type="image">.
     *
     * @param $src
     */
    protected function SetSrc($src)
    {
        $this->src = " src='".$src."' ";
    }

    /**
     * The step attribute specifies the legal number intervals for an <input> element.
     * Example: if step="3", legal numbers could be -3, 0, 3, 6, etc.
     * Tip: The step attribute can be used together with the max and min attributes to create a range of legal values.
     * Note: The step attribute works with the following input types: number, range, date, datetime, datetime-local, month, time and week.
     *
     * @param $step
     */
    protected function SetStep($step)
    {
        $this->step = " step='".$step."' ";
    }

    /**
     * The type attribute specifies the type of <input> element to display.
     * The default type is: text.
     * Tip: This is not a required attribute, but we think you should always include it.
     *
     * @param $type
     */
    protected function SetType($type)
    {
        $this->type = " type='".$type."' ";
    }

    /**
     * Sets the text that will be displayed after the control is rendered.
     *
     * @param string $text
     */
    protected function SetText($text)
    {
        $this->text = $text;
    }

    /**
     * The value attribute specifies the value of an <input> element.
     * The value attribute is used differently for different input types:
     *
     * For "button", "reset", and "submit" - it defines the text on the button.
     * For "text", "password", "hidden" - it defines the initial (default) value of the input field
     * For "checkbox", "radio", "image" - it defines the value associated with the input (this is also the value that is sent on submit)
     *
     * Note: The value attribute is required with <input type="checkbox"> and <input type="radio">.
     * Note: The value attribute cannot be used with <input type="file">.
     *
     * TODO: Value cannot be used with File element needs excluding.
     * TODO: Checkbox & Radio require value to be set add to validation.
     *
     * @param $value
     */
    public function SetValue($value)
    {
        $this->value = " value='".$value."' ";
    }

    /**
     * The width attribute specifies the width of the <input> element.
     *
     * Note: The width attribute is used only with <input type="image">.
     *
     * Tip: Always specify both the height and width attributes for images.
     *
     * If height and width are set, the space required for the image is reserved when the page is loaded.
     * However, without these attributes, the browser does not know the size of the image, and cannot reserve the appropriate space to it.
     * The effect will be that the page layout will change during loading (while the images load).
     *
     * @param $width
     */
    protected function SetWidth($width)
    {
        $this->width = " width='".$width."' ";
    }

}
